using System;
using Extensions.FPMath;
using Unity.Entities;

namespace Game.Core
{
    [Serializable]
    public unsafe struct AttackPropertyData
    {
        // 物理攻击
        public float MinMeleeAttack;
        public float MaxMeleeAttack;
        public float MinRangeAttack;
        public float MaxRangeAttack;
        public float AttackRange;
        public float AttackInterval;
        public float Hit;
        public float CritRate;
        public float CritRatio;
        
        // 法术攻击
        public float AbilityPower; // 法术强度
        public float Penetration; // 法术穿透
        public float CurAbilityPoint; // 当前法术值
        public float MaxAbilityPoint; // 最大法术值
        public float AbilityRecover; // 法术回复
        
        // 真实伤害
        public float ExtraDamage;

        public static AttackPropertyData operator +(AttackPropertyData a) => a;

        public static AttackPropertyData operator -(AttackPropertyData a) =>
            new AttackPropertyData()
            {
                MinMeleeAttack = -a.MinMeleeAttack,
                MaxMeleeAttack = -a.MaxMeleeAttack,
                MinRangeAttack = -a.MinRangeAttack,
                MaxRangeAttack = -a.MaxRangeAttack,
                AttackRange = -a.AttackRange,
                AttackInterval = -a.AttackInterval,
                Hit = -a.Hit,
                CritRate = -a.CritRate,
                CritRatio = -a.CritRatio,
                
                AbilityPower = -a.AbilityPower,
                Penetration = -a.Penetration,
                CurAbilityPoint = -a.CurAbilityPoint,
                MaxAbilityPoint = -a.MaxAbilityPoint,
                AbilityRecover = -a.AbilityRecover,
                
                ExtraDamage = -a.ExtraDamage,
            };

        public AttackPropertyData Add(AttackPropertyData* p)
        {
            AttackPropertyData r = new AttackPropertyData();
            r.MinMeleeAttack = MinMeleeAttack + p->MinMeleeAttack;
            r.MaxMeleeAttack = MaxMeleeAttack + p->MaxMeleeAttack;
            r.MinRangeAttack = MinRangeAttack + p->MinRangeAttack;
            r.MaxRangeAttack = MaxRangeAttack + p->MaxRangeAttack;
            r.AttackRange = AttackRange + p->AttackRange;
            r.AttackInterval = AttackInterval + p->AttackInterval;
            r.Hit = Hit + p->Hit;
            r.CritRate = CritRate + p->CritRate;
            r.CritRatio = CritRatio + p->CritRatio;
            
            r.AbilityPower = AbilityPower + p->AbilityPower;
            r.Penetration = Penetration + p->Penetration;
            r.CurAbilityPoint = CurAbilityPoint + p->CurAbilityPoint;
            r.MaxAbilityPoint = MaxAbilityPoint + p->MaxAbilityPoint;
            r.AbilityRecover = AbilityRecover + p->AbilityRecover;
            
            r.ExtraDamage = ExtraDamage + p->ExtraDamage;
            return r;
        }
        public static AttackPropertyData operator +(AttackPropertyData a, AttackPropertyData* b) => a.Add(b);
        public static AttackPropertyData operator +(AttackPropertyData a, AttackPropertyData b) => a.Add(&b);

        public AttackPropertyData Subtract(AttackPropertyData* p) => this + -(*p); 
        public static AttackPropertyData operator -(AttackPropertyData a, AttackPropertyData b) => a + (-b);

        public static implicit operator AttackPropertyData(PropertyInfo data)
        {
            return new AttackPropertyData
            {
                MinMeleeAttack = data.MinMeleeAttack,
                MaxMeleeAttack = data.MaxMeleeAttack,
                MinRangeAttack = data.MinRangeAttack,
                MaxRangeAttack = data.MaxRangeAttack,
                AttackRange = data.AttackRange,
                AttackInterval = data.AttackSpeed,
                Hit = data.Hit,
                CritRate = data.CritRate,
                CritRatio = data.CritRatio,
                
                AbilityPower = data.AbilityPower,
                Penetration = data.Penetration,
                CurAbilityPoint = data.MaxAbilityPoint,
                MaxAbilityPoint = data.MaxAbilityPoint,
                AbilityRecover = data.AbilityRecover,
                
                ExtraDamage = data.ExtraDamage, 
            };
        }
    }
}